{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "#@title 定义基本工具函数\n",
    "import tqdm\n",
    "import time\n",
    "def do_repeat(count: int, progress_bar=None, progress_title=None):\n",
    "    def fn(func):\n",
    "        ret_list = []\n",
    "        for i in (tqdm.tqdm(range(count), desc=progress_title) if progress_bar is None else progress_bar(range(count), title=progress_title)):\n",
    "            ret = func(step=i, count=count)\n",
    "            ret_list.append(ret)\n",
    "        return ret_list\n",
    "    return fn\n",
    "\n",
    "def measure_time(fn):\n",
    "    def wrapper(*args, **kwargs):\n",
    "        start_t = time.perf_counter()\n",
    "        ret = fn(*args, **kwargs)\n",
    "        end_t = time.perf_counter()\n",
    "        return ret, (end_t - start_t)\n",
    "    return wrapper\n",
    "\n",
    "def get_avg_value(list, start_index=0):\n",
    "    v = [x for _,x in list[start_index:]]\n",
    "    return 0 if len(v) == 0 else (sum(v) / len(v))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#@title 全局配置定义\n",
    "verbose = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Import MeloTTS_ONNX...\n",
      "Create instance of MeloTTS_ONNX...\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Building prefix dict from the default dictionary ...\n",
      "Loading model from cache C:\\Temp\\jieba.cache\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Speak some sentences and save to test.wav...\n",
      "['现在是10月24日10点07分45秒.', '今天的天气真nice.', '咱们一起去郊游吧.', '然后,', '咱们到hotel、garden里面去开个party.', '.', '好不好啊.']\n",
      "['现在是10月24日10点07分45秒.', '今天的天气真nice.', '咱们一起去郊游吧.', '然后, 咱们到hotel、garden里面去开个party.', '. 好不好啊.']\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Loading model cost 0.741 seconds.\n",
      "Prefix dict has been built successfully.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-1.4915683e-05  8.9676296e-06  5.4966172e-06 ...  0.0000000e+00\n",
      "  0.0000000e+00  0.0000000e+00]\n",
      "Measure time...\n"
     ]
    },
    {
     "ename": "NameError",
     "evalue": "name 'do_repeat' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[3], line 30\u001b[0m\n\u001b[0;32m     26\u001b[0m soundfile\u001b[38;5;241m.\u001b[39mwrite(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m./test.wav\u001b[39m\u001b[38;5;124m\"\u001b[39m, audio, samplerate\u001b[38;5;241m=\u001b[39mtts\u001b[38;5;241m.\u001b[39msample_rate)\n\u001b[0;32m     28\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mMeasure time...\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m---> 30\u001b[0m \u001b[38;5;129m@do_repeat\u001b[39m(\u001b[38;5;241m10\u001b[39m)\n\u001b[0;32m     31\u001b[0m \u001b[38;5;129m@measure_time\u001b[39m\n\u001b[0;32m     32\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mtts_time\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[0;32m     33\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m tts\u001b[38;5;241m.\u001b[39mspeak(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m今天天气真nice\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mZH\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[0;32m     35\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAverage time is \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mget_avg_value(tts_time)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124ms\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n",
      "\u001b[1;31mNameError\u001b[0m: name 'do_repeat' is not defined"
     ]
    }
   ],
   "source": [
    "#@title 测试TTS\n",
    "onnx_params = {\n",
    "    'provider_options': [{\n",
    "        'device_type': 'GPU'\n",
    "    }]\n",
    "}\n",
    "\n",
    "#session_opts = ort.SessionOptions()\n",
    "\n",
    "print(\"Import MeloTTS_ONNX...\")\n",
    "from melo_onnx import MeloTTS_ONNX\n",
    "\n",
    "print(\"Create instance of MeloTTS_ONNX...\")\n",
    "tts = MeloTTS_ONNX(\"./models/zh_mix_en\", verbose=verbose, execution_provider=\"CPU\", onnx_params=onnx_params)\n",
    "\n",
    "print(\"Speak some sentences and save to test.wav...\")\n",
    "from datetime import datetime\n",
    "now = datetime.now()\n",
    "now_text = now.strftime(\"%m月%d日%H点%M分%S秒\")\n",
    "# 格式化为字符串\n",
    "text = f\"现在是{now_text}。今天的天气真nice。咱们一起去郊游吧。然后，咱们到hotel、garden里面去开个party……好不好啊？\"\n",
    "audio = tts.speak(text, 'ZH')\n",
    "print(audio)\n",
    "\n",
    "import soundfile\n",
    "soundfile.write(\"./test.wav\", audio, samplerate=tts.sample_rate)\n",
    "\n",
    "print(\"Measure time...\")\n",
    "\n",
    "@do_repeat(10)\n",
    "@measure_time\n",
    "def tts_time(**kwargs):\n",
    "    return tts.speak('今天天气真nice', 'ZH')\n",
    "\n",
    "print(f\"Average time is {get_avg_value(tts_time)}s\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['今天的天气真nice.', '咱们一起去郊游吧.', '然后, 咱们到hotel、garden里面去开个party.', '. 好不好啊.']\n"
     ]
    }
   ],
   "source": [
    "#@title 句子分割测试调试\n",
    "from melo_onnx.text.split_utils import split_sentence\n",
    "s = split_sentence(\"今天的天气真nice。咱们一起去郊游吧。然后，咱们到hotel、garden里面去开个party……好不好啊？\", language_str=\"ZH_MIX_EN\")\n",
    "print(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(135680,)\n",
      "22050\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "100%|██████████| 10/10 [00:00<00:00, 16.09it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "average time of extracting the tone color is  0.06019485997967422\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "  0%|          | 0/10 [00:02<?, ?it/s]\n"
     ]
    },
    {
     "ename": "KeyboardInterrupt",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[3], line 24\u001b[0m\n\u001b[0;32m     18\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m tc\u001b[38;5;241m.\u001b[39mextract_tone_color(aa)\n\u001b[0;32m     20\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124maverage time of extracting the tone color is \u001b[39m\u001b[38;5;124m\"\u001b[39m, get_avg_value(extract_tone_color_time))\n\u001b[0;32m     22\u001b[0m \u001b[38;5;129;43m@do_repeat\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m10\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m     23\u001b[0m \u001b[38;5;129;43m@measure_time\u001b[39;49m\n\u001b[1;32m---> 24\u001b[0m \u001b[38;5;28;43;01mdef\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;21;43mtone_clone_time\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[0;32m     25\u001b[0m \u001b[43m    \u001b[49m\u001b[38;5;28;43;01mreturn\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtc\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtone_clone\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcc\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m     27\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124maverage time of cloning the tone color is \u001b[39m\u001b[38;5;124m\"\u001b[39m, get_avg_value(tone_clone_time))\n",
      "Cell \u001b[1;32mIn[2], line 8\u001b[0m, in \u001b[0;36mdo_repeat.<locals>.fn\u001b[1;34m(func)\u001b[0m\n\u001b[0;32m      6\u001b[0m ret_list \u001b[38;5;241m=\u001b[39m []\n\u001b[0;32m      7\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m (tqdm\u001b[38;5;241m.\u001b[39mtqdm(\u001b[38;5;28mrange\u001b[39m(count), desc\u001b[38;5;241m=\u001b[39mprogress_title) \u001b[38;5;28;01mif\u001b[39;00m progress_bar \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m progress_bar(\u001b[38;5;28mrange\u001b[39m(count), title\u001b[38;5;241m=\u001b[39mprogress_title)):\n\u001b[1;32m----> 8\u001b[0m     ret \u001b[38;5;241m=\u001b[39m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43mstep\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mi\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcount\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcount\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m      9\u001b[0m     ret_list\u001b[38;5;241m.\u001b[39mappend(ret)\n\u001b[0;32m     10\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m ret_list\n",
      "Cell \u001b[1;32mIn[2], line 16\u001b[0m, in \u001b[0;36mmeasure_time.<locals>.wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m     14\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mwrapper\u001b[39m(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[0;32m     15\u001b[0m     start_t \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mperf_counter()\n\u001b[1;32m---> 16\u001b[0m     ret \u001b[38;5;241m=\u001b[39m fn(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m     17\u001b[0m     end_t \u001b[38;5;241m=\u001b[39m time\u001b[38;5;241m.\u001b[39mperf_counter()\n\u001b[0;32m     18\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m ret, (end_t \u001b[38;5;241m-\u001b[39m start_t)\n",
      "Cell \u001b[1;32mIn[3], line 25\u001b[0m, in \u001b[0;36mtone_clone_time\u001b[1;34m(**kwargs)\u001b[0m\n\u001b[0;32m     22\u001b[0m \u001b[38;5;129m@do_repeat\u001b[39m(\u001b[38;5;241m10\u001b[39m)\n\u001b[0;32m     23\u001b[0m \u001b[38;5;129m@measure_time\u001b[39m\n\u001b[0;32m     24\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mtone_clone_time\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m---> 25\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mtc\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mtone_clone\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcc\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mb\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[1;32md:\\.Test\\TTS\\MeloTTS-ONNX\\melo_onnx\\main.py:286\u001b[0m, in \u001b[0;36mOpenVoiceToneClone_ONNX.tone_clone\u001b[1;34m(self, audio, target_tone_color, tau)\u001b[0m\n\u001b[0;32m    284\u001b[0m src \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mtranspose(src, (\u001b[38;5;241m0\u001b[39m, \u001b[38;5;241m2\u001b[39m, \u001b[38;5;241m1\u001b[39m))\n\u001b[0;32m    285\u001b[0m src_length \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marray([src\u001b[38;5;241m.\u001b[39mshape[\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m]], dtype\u001b[38;5;241m=\u001b[39mnp\u001b[38;5;241m.\u001b[39mint64)\n\u001b[1;32m--> 286\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__tc_infer\u001b[49m\u001b[43m(\u001b[49m\u001b[43maudio\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msrc\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43maudio_length\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msrc_length\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msrc_tone\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msrc_tone\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdest_tone\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtarget_tone_color\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtau\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marray\u001b[49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[43mtau\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdtype\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfloat32\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[1;32md:\\.Test\\TTS\\MeloTTS-ONNX\\melo_onnx\\main.py:221\u001b[0m, in \u001b[0;36mOpenVoiceToneClone_ONNX.__init__.<locals>.se_infer_factor.<locals>.<lambda>\u001b[1;34m(**kwargs)\u001b[0m\n\u001b[0;32m    220\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mse_infer_factor\u001b[39m(session):\n\u001b[1;32m--> 221\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;01mlambda\u001b[39;00m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: \u001b[43msession\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m[\u001b[38;5;241m0\u001b[39m][\u001b[38;5;241m0\u001b[39m, \u001b[38;5;241m0\u001b[39m]\n",
      "File \u001b[1;32md:\\.Test\\TTS\\MeloTTS-ONNX\\venv\\lib\\site-packages\\onnxruntime\\capi\\onnxruntime_inference_collection.py:220\u001b[0m, in \u001b[0;36mSession.run\u001b[1;34m(self, output_names, input_feed, run_options)\u001b[0m\n\u001b[0;32m    218\u001b[0m     output_names \u001b[38;5;241m=\u001b[39m [output\u001b[38;5;241m.\u001b[39mname \u001b[38;5;28;01mfor\u001b[39;00m output \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_outputs_meta]\n\u001b[0;32m    219\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 220\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_sess\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43moutput_names\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minput_feed\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_options\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m    221\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m C\u001b[38;5;241m.\u001b[39mEPFail \u001b[38;5;28;01mas\u001b[39;00m err:\n\u001b[0;32m    222\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_enable_fallback:\n",
      "\u001b[1;31mKeyboardInterrupt\u001b[0m: "
     ]
    }
   ],
   "source": [
    "#@title 测试音色克隆\n",
    "from melo_onnx import OpenVoiceToneClone_ONNX\n",
    "tc = OpenVoiceToneClone_ONNX(\"./models/tone_clone\")\n",
    "import soundfile\n",
    "a = soundfile.read(\"..\\\\OpenVoice\\\\audio_segments\\\\shenmiao_2309021235\\\\wavs\\\\shenmiao_2309021235_seg0.wav\", dtype='float32')\n",
    "aa = tc.resample(a[0], a[1])\n",
    "b = tc.extract_tone_color(aa)\n",
    "c = soundfile.read(\"C:\\\\Users\\\\Season\\\\Desktop\\\\mysound\\\\myself\\\\001.wav\", dtype='float32')\n",
    "cc = tc.resample(c[0], c[1])\n",
    "d = tc.tone_clone(cc, b)\n",
    "print(d.shape)\n",
    "print(tc.sample_rate)\n",
    "soundfile.write(\"./tc_test.wav\", d, tc.sample_rate)\n",
    "\n",
    "@do_repeat(10)\n",
    "@measure_time\n",
    "def extract_tone_color_time(**kwargs):\n",
    "    return tc.extract_tone_color(aa)\n",
    "\n",
    "print(\"average time of extracting the tone color is \", get_avg_value(extract_tone_color_time))\n",
    "\n",
    "@do_repeat(10)\n",
    "@measure_time\n",
    "def tone_clone_time(**kwargs):\n",
    "    return tc.tone_clone(cc, b)\n",
    "\n",
    "print(\"average time of cloning the tone color is \", get_avg_value(tone_clone_time))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
